<?php

namespace App\Services\Iot;

use App\Model\ChargeDetail;
use App\Model\Normal;

/**
 * Created by PhpStorm.
 * User: liuta
 * Date: 2018/9/29
 * Time: 18:44
 */
class IotService1
{
    public static $mqtt = null;
    private static string $server = '121.40.83.20';
    private static int $port = 1883;
    private static ?string $username = 'admin';
    private static ?string $password = 'administrator';


    /**
     * @return \PhpMqtt\Client\MqttClient
     * @throws \PhpMqtt\Client\Exceptions\ProtocolNotSupportedException
     */
    public static function getClient()
    {
        $connectSettings = (new \PhpMqtt\Client\ConnectionSettings())
            ->setUsername(self::$username)
            ->setPassword(self::$password);
        $mqtt = new \PhpMqtt\Client\MqttClient(self::$server, self::$port);
        $mqtt->connect($connectSettings,true);
        return $mqtt;
    }

    public static function replaySomeThing($imei)
    {
        $mqtt = self::getClient();
        $msg = chr(0x3c);
        $msg .= chr(0x00);
        $msg .= chr(date('Y') - 2000);
        $msg .= chr(date('m'));
        $msg .= chr(date('d'));
        $msg .= chr(date('H'));
        $msg .= chr(date('i'));
        $msg .= chr(date('s'));
        $msg .= chr(0x05);
        $msg .= chr(0x1c);

        $mqtt->publish('/v1/device/' . $imei . '/tx', $msg, 1);
    }


    /**
     * @param       $imei string 通讯号
     * @param       $cmd  int 命令码
     * @param array $data
     *                    !!!所有参数涉及到16进制的 均转换为10进制在传递
     */
    public static function send($imei, $cmd, array $data)
    {
        //Change client name to something unique
        $connectSettings = (new \PhpMqtt\Client\ConnectionSettings())
            ->setUsername(self::$username)
            ->setPassword(self::$password);
        $mqtt = new \PhpMqtt\Client\MqttClient(self::$server, self::$port);
        $mqtt->connect($connectSettings,true);
        //LEN 单字节 CMD开始算的命令字节长度
        $len = count($data) + 3;
        //RESULT 单字节 命令是否成功, 0x01成功; 0x00失败; 0xFF无网络; 发起方固定为0x01
        $result = 0x00;
        //SUM 单字节 LEN CMD RESULT DATA的异或值
        $sum = $len ^ $cmd ^ $result;


        //记录日志
        $fullData = array_merge([
            0xAA,
            $len,
            $cmd,
            $result,
        ], $data, [$sum]);
//        IotLog::record($imei, IotLog::TYPE_SEND, $fullData);

        $msg = null;
//            $msg.=chr(0xAA); //SOP 单字节字头 固定AA
//            $msg.=chr(0x08); //LEN 单字节 CMD开始算的命令字节长度
//            $msg.=chr(0x04); //CMD 单字节 命令
//            $msg.=chr(0x00); //RESULT 单字节 命令是否成功, 0x01成功; 0x00失败; 0xFF无网络; 发起方固定为0x01
//            //DATA 不定长  数据字节
//            $msg.=chr(0x04);
//            $msg.=chr(0x00);
//            $msg.=chr(0x14);
//            $msg.=chr(0x00);
//            $msg.=chr(0x02);
//            //DATA END -----
//            $msg.=chr(0x1e); //SUM 单字节 LEN CMD RESULT DATA的异或值
//
//            $imei = 866289037705763;

            $msg = chr(0xAA); //SOP 单字节字头 固定AA
            $msg .= chr($len);
            $msg .= chr($cmd); //CMD 单字节 命令
            $msg .= chr($result);

            foreach ($data as $i => $item) {
                $msg .= chr($item);
                $sum = $sum ^ $item;
            }

            $msg .= chr($sum);

            //记录一下日志
            $strlen    = strlen($msg);
            $strSource = [];
            for ($i = 0; $i < $strlen; $i++) {

                # code..
                $strSource[] = dechex(ord(substr($msg, $i, 1)));
            }
            logger('send message ' . $imei, $strSource);
            Normal::logger('send data ' . $imei.'----'.json_encode($strSource), 'order-queue');
//            Normal::logger('send message ' . $imei.'----'.$msg, 'order-queue');

            $mqtt->publish('/v1/device/' . $imei . '/tx', $msg);
            $mqtt->disconnect();
    }

//    /**
//     * @param $sn
//     * @return bool
//     * 查询设备是否在线
//     */
//    public static function queryDeviceOnlineStatus($sn)
//    {
//
////        return (boolean) Arr::get($result, 'online');
//    }


    public static function queryDeviceStatus($imei)
    {
        self::send($imei, 0x01, [
            0x00,
        ]);
    }

    public static function stop($imei, $port)
    {
        self::send($imei, 0x0D, [
            $port,
            0x01
        ]);
    }


    public static function updateUrl($imei,$path='/device/eBIKE_ML307R_Upgrade_v1.01.004.bin',$url='http://yimits.oss-cn-beijing.aliyuncs.com:80'){
        $url = str_pad($url, 64, "\0", STR_PAD_RIGHT);
        $path = str_pad($path, 64, "\0", STR_PAD_RIGHT);
        // 将字符串转换为字节数组
        $urlBytes = array_map('ord', str_split($url));
        $pathBytes = array_map('ord', str_split($path));
        // 合并URL和PATH的字节数组
        $data = array_merge($urlBytes, $pathBytes);
        self::send($imei,0xA3,$data);
    }



    public static function replayStop($imei, $port)
    {
        self::send($imei, 0x16, [
            $port,
        ]);
    }


    /**
     * @param $imei
     * @param $port
     * @param $minutes
     * @param $fee float 钱 单位:元
     */
    public static function start($imei, $port, $minutes, $fee, $elec = 100, $mode = 1)
    {
        Normal::logger('start params','iotevent','info');
        $duration1 = floor($minutes / 256);
        $duration2 = $minutes % 256;

        $fee1 = floor($fee * 10 / 256);
        $fee2 = floor($fee * 10 % 256);
//        $device = Device::query()->where('iot_sn',$imei)->first();

//        if($device->is_new == 1){
//            $elec1 = floor($elec / 256);
//            $elec2 = $elec % 256;
//
//            self::send($imei, 0x14, [
//                //端口号
//                $port,
//
//                //费用
//                $fee1,
//                $fee2,
//
//                //时间
//                $duration1,
//                $duration2,
//
//
//                //可用电量
//                $elec1,
//                $elec2,
//
//                //显示模式
//                $mode
//            ]);
//        }else{
            self::send($imei, 0x04, [
                //端口号
                $port,

                //费用
                $fee1,
                $fee2,

                //时间
                $duration1,
                $duration2,
            ]);
//        }
    }

    public static function startNew($imei,$port,$charge,$fee,$minutes,$scale)
    {
        $levelCount = 0;
        $fee1 = floor($fee * 100 / 256);
        $fee2 = floor($fee * 100 % 256);
        if($charge->type == 1){
            if($charge->is_autoload == 1){
                $mode = 2;
                $elecPrice1 = 0;
                $elecPrice2 = 0;
                $servicePrice1 = 0;
                $servicePrice2 = 0;
                $levelCount = ChargeDetail::where('charge_option_id',$charge->id)
                    ->where('is_del',1)
                    ->where('type',1)->count();
            }else{
                $mode = 1;
                $fee1 = floor($minutes / 256);
                $fee2 = $minutes % 256;
                $elecPrice1 = 0;
                $elecPrice2 = 0;
                $servicePrice1 = 0;
                $servicePrice2 = 0;
            }
        }else{
            $elecPrice = $charge->elec_price*1000;
            $elecPrice1 = floor($elecPrice/ 256);;
            $elecPrice2 = $elecPrice % 256;
            if($charge->service_type == 1){
                $mode = 3;
                $servicePrice = $charge->service_fee*1000;
                $servicePrice1= floor($servicePrice/ 256);
                $servicePrice2= $servicePrice % 256;
            }else{
                $mode = 4;
                $servicePrice1 = 0;
                $servicePrice2 = 0;
                $levelCount = ChargeDetail::where('charge_option_id',$charge->id)
                ->where('is_del',1)
                ->where('type',4)->count();
            }
        }
        $data = [
            //端口号
            $port,
            $mode,
            $scale,
            //费用或时间
            $fee1,
            $fee2,
            //电价
            $elecPrice1,
            $elecPrice2,
            //服务费
            $servicePrice1,
            $servicePrice2,
            //分档个数
            $levelCount

        ];

        if($mode == 2){
            $chargeDetails =  ChargeDetail::where('charge_option_id',$charge->id)
                ->where('is_del',1)
                ->where('type',1)->get();
            foreach($chargeDetails as $v){
                $power = $v->max_power;
                $power1 = floor($power/ 256);
                array_push($data,$power1);
                $power2= $power % 256;
                array_push($data,$power2);
                $power_price = $v->minutes;
                $power_price1 = floor($power_price/ 256);
                array_push($data,$power_price1);
                $power_price2 = $power_price % 256;
                array_push($data,$power_price2);
            }
        }
        if($mode == 4){
            $chargeDetails =  ChargeDetail::where('charge_option_id',$charge->id)
                ->where('is_del',1)
                ->where('type',4)->get();
            foreach($chargeDetails as $v){
                $power = $v->max_power;
                $power1 = floor($power/ 256);
                array_push($data,$power1);
                $power2= $power % 256;
                array_push($data,$power2);
                $power_price = $v->fee*1000;
                $power_price1 = floor($power_price/ 256);
                array_push($data,$power_price1);
                $power_price2 = $power_price % 256;
                array_push($data,$power_price2);
            }
        }
        self::send($imei, 0x14,$data);
    }


    public static function readParams($imei)
    {
        self::send($imei, 0x1E, [
            0x00
        ]);
    }

    public static function queryMoney($imei)
    {
        self::send($imei, 0x07, [
            0x00
        ]);
    }


    public static function updateParams($imei, array $params)
    {
        self::send($imei, 0x18, $params);
    }


    public static function readPower($imei,$port){
        self::send($imei,0x15, [$port]);
    }



}
